
# ​​object 是类​  object 是 type 的实例​    --  因为 type 是创建类的元类，而 object 是一个类
# type 是 object 的子类​  ----  因为 type 是一个类，所有类必须继承 object。
# type 是自己的实例​   -----  type 是自己的元类，形成闭环
# 



# 什么是元类----------》 继承type类   --------- 只能继承一代， 间接继承的是普通类，不是元类
# Python 的继承机制不会自动调用元类的 __new__​​，除非 User 的元类是 ModelMeta（即 metaclass=ModelMeta）
# 如何使用 元类， 除了 metaclass=  这种方式 还可以 ----》  通过父类传递元类​（就是这个类继承了一个  metaclass=ModelMeta 的类）
                                                #  此时不不能写   metaclass=  ， 直接继承就行



# --------------------------------- __module__ ---------------------------------
# 表示定义该对象的模块名​​（即它所在的 .py 文件）。
# 对于内置类型（如 int、str），__module__ 通常是 builtins。
# 如果是直接运行当前脚本，__module__ 会是 __main__：  
#           ----动态创建的类也是 __main__ ------  DynamicClass = type('DynamicClass', (), {})  
# 对于导入的模块，__module__ 是模块的实际名称



# --------------------------------- __qualname__ ---------------------------------
# 表示对象的限定名称（qualified name）​​，即从模块顶层到该对象的完整路径，包括外层类（嵌套类或方法时会体现层次关系）


#   ------------------普通类------------------
def foo(): pass
class Bar: pass

print(foo.__qualname__)  # 输出: 'foo'
print(Bar.__qualname__)  # 输出: 'Bar'



#   ------------------嵌套类或方法------------------
class Outer:
    class Inner:
        def method(self): pass

print(Outer.Inner.__qualname__)       # 输出: 'Outer.Inner'
print(Outer.Inner.method.__qualname__) # 输出: 'Outer.Inner.method'

#                 __name__ 只返回对象本身的名称，不包含外层信息


# 实际应用场景
#     动态导入或反射​
import importlib
# 通过 __module__ 动态导入类
module = importlib.import_module(MyClass.__module__)
cls = getattr(module, MyClass.__qualname__)


#    调试日志​
def log(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__module__}.{func.__qualname__}")
        return func(*args, **kwargs)
    return wrapper

@log
def example(): pass

example()  # 输出: Calling __main__.example

# 序列化或文档生成​​  ：生成清晰的函数/类路径（如 API 文档）




# --------------------------------- __new__ ---------------------------------

# __new__ 是一个特殊的静态方法（尽管通常不需要显式声明为 @staticmethod），它负责创建并返回一个类的实例。
# 它是对象实例化过程中最先被调用的方法，甚至在 __init__ 之前执行。

# 控制实例的创建过程
# __new__ 决定是否创建一个新实例，或返回一个现有实例（例如实现单例模式）
# 与 __init__ 的区别
# __new__：创建实例（分配内存）。
# __init__：初始化实例（设置属性）。
# 若 __new__ 不返回实例，__init__ 不会被调用

# 继承不可变类型时的关键角色
# 修改不可变类型（如 int, str, tuple）的实例化行为时，必须重写 __new__，因为它们在创建后无法被 __init__ 修改
class UpperStr(str):
    def __new__(cls, value):
        print("--------__new__---------")
        # 必须在创建实例时修改值
        modified_value = value.upper()
        # 当调用 UpperStr("hello") 时，"hello" 会同时传递给 __new__ 和 __init__（如果 __new__ 返回实例）
        return super().__new__(cls, modified_value)   # 如果这里不返回 或者返回None，__init__ 不会被调用

    # str 是不可变类型，其 __init__ 方法在 Python 中通常不接受参数（因为初始化已在 __new__ 中完成）
    def __init__(self, value):
        print(f"-------------{value}---------------")

s = UpperStr("hello")
print(s)  # "HELLO"


# 调用顺序：__new__ → （返回实例） → __init__。
# 必须返回实例：通常通过 super().__new__(cls) 实现。
# 用途：单例、不可变类型定制、元类编程、资源复用等。



# --------------------------------- __set_name__ ---------------------------------
class Validator:
    def __set_name__(self, owner, name):
        print(f"设置名称: {name}")
        self.private_name = f"_{name}"
    
    def __get__(self, obj, objtype=None):
        return getattr(obj, self.private_name)
    
    def __set__(self, obj, value):
        setattr(obj, self.private_name, value)

class Person:
    name = Validator()  # 自动调用 __set_name__(Validator, Person, 'name')
    age = Validator()   # 自动调用 __set_name__(Validator, Person, 'age')

# 使用时
p = Person()
p.name = "张三"
print(p.name)  # 输出: 张三